﻿''' <summary>
''' This version of the library references version 10 of the ReportViewer control which is only compatible with SQL Server 2008 and Report Builder 2.0
''' Note: in addition to the required references of Microsoft.ReportViewer.Common and .Winforms, other DLLs called ProcessingObjectModel and DataVisualization must be included
''' (they are normally installed in the GAC, but I want to do XCOPY deployment and not run ReportViewer installer)
''' </summary>
Public Class frmReporting

    Private _ServerURL As String, _UserName As String, _Password As String, _ReportPath As String, _ReportDir As String, _ReportName As String, _Timeout As Integer
    Private _Project As WRDB.Project.clsProject
    Private ReportInfo As WRDB.Reports.RdlViewer.clsReportInfo
    Public WithEvents cboReports As ToolStripComboBox = Nothing
    Public WithEvents btnConfig As ToolStripButton = Nothing
    Public WithEvents btnReselect As ToolStripButton = Nothing

    ''' <summary>
    ''' Instantiate form
    ''' </summary>
    ''' <param name="ServerURL">URL of report server (e.g., http://hidromet/ReportServer) </param>
    ''' <param name="UserName">User name (blank for Windows authentication)</param>
    ''' <param name="Password">Password</param>
    ''' <param name="ReportPath">Path to report location (e.g., /Produccion/BDH/Informes de Calidad de Agua/)</param>
    ''' <param name="ReportDir">Directory of .RDL files (only used if ReportName ends in .RDL)</param>
    ''' <param name="ReportName">Name of report on server (e.g., BDHC0001)</param>
    ''' <param name="IsStandAlone">If true, will allow user to reselect report and configure</param>
    ''' <remarks></remarks>
    Public Sub New(ServerURL As String, UserName As String, Password As String, ReportPath As String, ReportDir As String, Timeout As Integer, ReportName As String,
                   Project As WRDB.Project.clsProject, Optional IsStandAlone As Boolean = False)
        Try

            InitializeComponent()
            _ServerURL = ServerURL
            _UserName = UserName
            _Password = Password
            _ReportPath = ReportPath
            _ReportDir = ReportDir
            _Timeout = Timeout
            'report path must begin and end with slashes
            If Not _ReportPath.StartsWith("/") Then _ReportPath = "/" & _ReportPath
            If Not _ReportPath.EndsWith("/") Then _ReportPath &= "/"
            If Not _ReportDir.EndsWith("\") Then _ReportDir &= "\"
            _ReportName = ReportName
            _Project = Project

            If _ReportDir <> "" And IsStandAlone Then 'is local report; add combobox with list of available reports
                Dim ts As ToolStrip = ReportViewer1.Controls.Find("toolStrip1", True)(0)
                btnConfig = New ToolStripButton("Config")
                btnConfig.Alignment = ToolStripItemAlignment.Right
                btnConfig.ToolTipText = "Configure WRDB Reporting Tool"
                ts.Items.Add(btnConfig)
                cboReports = New ToolStripComboBox("Reports")
                With cboReports
                    .Alignment = ToolStripItemAlignment.Right
                    If Not My.Computer.FileSystem.DirectoryExists(_ReportDir) Then
                        WarningMsgFmt("Unable to find specified report directory\n\n{0}\n\nPlease reconfigure reports to point to valid directory.", _ReportDir.Replace("\", "\\"))
                        Exit Sub
                    End If
                    For Each f As String In My.Computer.FileSystem.GetFiles(_ReportDir, FileIO.SearchOption.SearchTopLevelOnly, New String() {"*.rdl"})
                        .Items.Add(IO.Path.GetFileNameWithoutExtension(f))
                    Next
                    .Sorted = True
                    .DropDownStyle = ComboBoxStyle.DropDownList
                    .Width = 200
                    .DropDownWidth = .Width * 2
                    .ToolTipText = "Select report from list"
                    ts.Items.Add(cboReports)
                End With
                btnReselect = New ToolStripButton("Reselect")
                btnReselect.Alignment = ToolStripItemAlignment.Right
                btnReselect.ToolTipText = "Reselect parameters and refresh"
                ts.Items.Add(btnReselect)
            End If


        Catch ex As Exception

            ErrorMsg(, ex)

        End Try

    End Sub

    Private Sub frmReporting_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        SaveWindowPos("WRDB", Me)
    End Sub

    Private Sub frmReporting_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            GetWindowPos("WRDB", Me)
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Function GetParameters() As Boolean
        Try

            If ReportInfo.ReportParameters.Count = 0 Then Return True
            Dim frm As New frmParameters(_Project, ReportInfo)
            If frm.ShowDialog(Me) = Windows.Forms.DialogResult.Cancel Then
                Return False
            Else
                For Each parm As Reports.RdlViewer.ReportParmInfo In ReportInfo.ReportParameters
                    Dim reportparm As New Microsoft.Reporting.WinForms.ReportParameter(parm.Name, parm.Value, True)
                    ReportViewer1.LocalReport.SetParameters(reportparm)
                Next
            End If

            Return True

        Catch ex As Exception

            ErrorMsg(ex.InnerException.ToString, ex)
            Return False

        End Try

    End Function

    Private Sub frmReporting_MenuComplete(sender As Object, e As EventArgs) Handles Me.MenuComplete

    End Sub

    Private Sub frmReporting_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
        Try
            Me.Cursor = Cursors.WaitCursor
            Application.DoEvents()

            With ReportViewer1
                If _ReportDir <> "" Then 'must be RDL report

                    If cboReports IsNot Nothing AndAlso
                        cboReports.Items.Contains(IO.Path.GetFileNameWithoutExtension(_ReportName)) AndAlso
                        My.Computer.FileSystem.FileExists(IO.Path.Combine(_ReportDir, _ReportName)) Then
                        cboReports.Text = IO.Path.GetFileNameWithoutExtension(_ReportName)
                    Else
                        _ReportName = ""
                        'RefreshLocalReport()
                    End If

                Else
                'view report stored on server
                .ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Remote
                With .ServerReport
                    .Timeout = _Timeout * 1000
                    .ReportServerUrl = New System.Uri(_ServerURL, System.UriKind.Absolute)
                    If _UserName <> "" Then
                        .ReportServerCredentials.NetworkCredentials = New System.Net.NetworkCredential(_UserName, _Password)
                    Else
                        .ReportServerCredentials.NetworkCredentials = System.Net.CredentialCache.DefaultCredentials
                    End If
                    .ReportPath = _ReportPath & _ReportName
                End With
                End If
                .RefreshReport()
            End With
        Catch ex As Exception
            ErrorMsg(, ex)
            Close()
        Finally
            Me.Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub RefreshLocalReport()

        Try

            If Not My.Computer.FileSystem.FileExists(_ReportDir & _ReportName) Then
                WarningMsgFmt("Unable to find specified report:\n\n{0}", (_ReportDir & _ReportName).Replace("\", "\\"))
                Exit Sub
            End If

            If cboReports IsNot Nothing Then cboReports.Enabled = False

            'note that ReportViewer does not automatically bind and fill datasource, so report is inspected and bound here
            'see http://www.gotreportviewer.com for examples

            'find name of dataset that was used when report was designed

            'if same report, do not reinitialize
            Static LastReport As String = ""

            If ReportInfo Is Nothing OrElse _ReportDir & _ReportName <> LastReport Then
                ReportInfo = New Reports.RdlViewer.clsReportInfo(_ReportDir & _ReportName)
                ReportInfo.Initialize()
                LastReport = _ReportDir & _ReportName
            End If

            With ReportViewer1

                .Reset()

                'load report from disk file for local processing
                .ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Local

                With .LocalReport
                    .ReportPath = _ReportDir & _ReportName

                    If GetParameters() Then
                        For Each dsName As String In .GetDataSourceNames
                            Dim dt As DataTable = Nothing
                            Select Case dsName
                                Case "Metricos" 'use a custom routine to fill a datatable under program control to simplify the design in reportbuilder
                                    dt = clsReportMetricos.GetData(_Project, .GetParameters)
                                Case Else 'this is the original approach where the tables identified in report (or WRDB_Tempdata) is queried to fill the datatable
                                    dt = ReportInfo.GetData(dsName, .GetParameters, _Project)
                            End Select
                            If dt IsNot Nothing Then
                                .DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource(dsName, dt))
                            End If
                        Next
                    End If
                End With

                'If GetParameters() Then .RefreshReport()
                .RefreshReport()
            End With

        Catch ex As Exception

            ErrorMsg(, ex)

        Finally

            If cboReports IsNot Nothing Then cboReports.Enabled = True

        End Try

    End Sub

    Private Sub cboReports_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles cboReports.SelectedIndexChanged
        Try

            cboReports.ToolTipText = cboReports.Text
            _ReportName = cboReports.Text & ".rdl"
            RefreshLocalReport()


        Catch ex As Exception

            ErrorMsg(, ex)

        End Try

    End Sub

    Private Sub btnConfig_Click(sender As Object, e As System.EventArgs) Handles btnConfig.Click
        Try

            With New frmConfigWRDB(_Project.Name, _ReportDir)
                If .ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
                    _Project = New WRDB.Project.clsProject(.ProjectName)
                    _ReportDir = .ReportDir
                End If
                .Dispose()
            End With


        Catch ex As Exception

            ErrorMsg(, ex)

        End Try

    End Sub

    Private Sub btnReselect_Click(sender As Object, e As System.EventArgs) Handles btnReselect.Click
        Try

            RefreshLocalReport()


        Catch ex As Exception

            ErrorMsg(, ex)

        End Try

    End Sub
End Class